#include "CToastBox.h"
#include <QTimerEvent>
#include <QTimer>
#include <QEvent>
#include <QApplication>
#include <QDesktopWidget>
#include <QPainter>
#include <QFontDatabase>

#define DEFAULT_WIDTH	360
#define DEFAULT_HEIGHT	300

void CToastBox::Info(QWidget * parent, const QString & title, const QString & content, bool modal)
{
	auto box = new CToastBox(EToastBoxType_Info, parent, title, content, modal);
	box->show();
}

void CToastBox::Warn(QWidget * parent, const QString & title, const QString & content, bool modal)
{
	auto box = new CToastBox(EToastBoxType_Warn, parent, title, content, modal);
	box->show();
}

void CToastBox::Error(QWidget * parent, const QString & title, const QString & content, bool modal)
{
	auto box = new CToastBox(EToastBoxType_Error, parent, title, content, modal);
	box->show();
}

void CToastBox::Success(QWidget * parent, const QString & title, const QString & content, bool modal)
{
	auto box = new CToastBox(EToastBoxType_Success, parent, title, content, modal);
	box->show();
}

bool CToastBox::Enable_icon_ = false;
bool CToastBox::Enable_title_ = false;
bool CToastBox::Enable_mask_ = false;
int CToastBox::Alpha_ = 100;
int CToastBox::Timeout_ = 3000;
CToastBox::CToastBox(EToastBoxType type, QWidget * parent, const QString & title, const QString & content, bool modal)
	: parent_(parent)
	, type_(type)
	, title_(title)
    , content_(content)
    , auto_close_(true)
    , icon_(QPixmap(":/img/toast_icon.png"))
{
	if (modal)
	{
		setAttribute(Qt::WA_ShowModal, true);
	}

	if (parent != Q_NULLPTR)
	{
		parent_ = parent;
		parent_->installEventFilter(this);
		setParent(parent_);
		resize(parent->size());
        // setGeometry(parent->geometry());
	}
	else
	{
		setGeometry(QApplication::desktop()->geometry());
		resize(QApplication::desktop()->size());
    }

    /// 设置图标
    switch (type)
    {
    case EToastBoxType_Success:
        icon_ = QPixmap(":/icon/icon_success.png");
    default:
        icon_ = QPixmap(":/icon/icon_error.png");
    }

    setWindowFlag(Qt::Tool);
    setWindowFlag(Qt::FramelessWindowHint);
	setAttribute(Qt::WA_AlwaysStackOnTop, true); 
    setAttribute(Qt::WA_TranslucentBackground, true);
}

void CToastBox::timerEvent(QTimerEvent * event)
{
	QWidget::timerEvent(event);
}

void CToastBox::paintEvent(QPaintEvent * event)
{
	QPainter painter(this); 
	painter.setRenderHint(QPainter::Antialiasing, true);
	painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
	if (Enable_mask_)
	{
		painter.fillRect(rect(), QColor(0, 0, 0, Alpha_));
	}

	// draw content rect
	QRect rect_main = this->rect();
	QRect rect_content(QPoint(
		rect_main.width() / 2 - DEFAULT_WIDTH / 2,
		rect_main.height() / 2 - DEFAULT_HEIGHT / 2),
		QSize(DEFAULT_WIDTH, DEFAULT_HEIGHT));
	QPainterPath path;
	path.addRoundedRect(rect_content, 20, 20);
    painter.fillPath(path, QColor(0xff, 0xff, 0xff));

	// draw text
	QFont font;
    font.setFamily("Microsoft YaHei");
    font.setPixelSize(24);
	QFontMetrics metrics(font);
	int font_width = metrics.width(content_);
	int font_height = metrics.height();
	QString str = content_;
	if (font_width > DEFAULT_WIDTH - 60)
	{
        str = metrics.elidedText(content_, Qt::ElideRight, DEFAULT_WIDTH - 60);
	}
	QRect rect_text = QRect(QPoint(
		rect_content.bottomLeft().x() + 30,
        rect_content.bottomLeft().y() - 150),
        QSize(DEFAULT_WIDTH - 60, 150));
    painter.setPen(QColor(0x00, 0x00, 0x00));
	painter.setFont(font);
	painter.drawText(rect_text, content_, QTextOption(Qt::AlignCenter));

	// draw icon
	QRect rect_icon = QRect(QPoint(
		rect_content.topLeft().x() + rect_content.width() / 2 - icon_.width() / 2,
		rect_content.topLeft().y() + 30),
		QSize(icon_.size()));
	painter.drawPixmap(rect_icon, icon_);
}

void CToastBox::mousePressEvent(QMouseEvent * event)
{
	auto_close_ = false;
    close();
	QWidget::mousePressEvent(event);
}

void CToastBox::showEvent(QShowEvent * event)
{
    QTimer::singleShot(Timeout_, this, [this]() {
        if (!auto_close_) return;
        close();
    });

	QWidget::showEvent(event);
}

void CToastBox::closeEvent(QCloseEvent * event)
{
	QWidget::closeEvent(event);
}

bool CToastBox::eventFilter(QObject * watched, QEvent * event)
{
	if (qobject_cast<QWidget*>(watched) == parent_)
	{
		if (event->type() == QEvent::Resize || event->type() == QEvent::Move)
		{
			setGeometry(parent_->geometry());
			update();
		}
	}

	return QWidget::eventFilter(watched, event);
}
